package drds.plus.sql_process.optimizer;

import drds.plus.common.model.Application;
import drds.plus.common.thread_local.ThreadLocalMap;
import drds.plus.sql_process.abstract_syntax_tree.configuration.manager.IndexManager;
import drds.plus.sql_process.abstract_syntax_tree.configuration.manager.SchemaManager;
import drds.plus.sql_process.optimizer.cost_esitimater.statistics.StatisticsManager;
import drds.plus.sql_process.parser.SqlParseManager;
import drds.plus.sql_process.rule.RouteOptimizer;
import lombok.Getter;
import lombok.Setter;

/**
 * 优化器上下文，主要解决一些共享上下文对象，因为不考虑spring进行IOC控制，所以一些对象/工具之间的依赖就很蛋疼，就搞了这么一个上下文
 *
 * <pre>
 * 考虑基于ThreadLocal进行上下文传递，几个原因：
 * 1. 减少context传递，node/expression/plan基本都是无状态的，不希望某个特定代码需要依赖context，而导致整个链路对象都需要传递context上下文
 * 2. context上下文中的对象，本身为支持线程安全，每个tddl客户端实例只有一份，一个jvm实例允许多个tddl客户端实例，所以不能搞成static对象
 * </pre>
 */
public class OptimizerContext {

    private static final String OPTIMIZER_CONTEXT_KEY = "_optimizer_context_";
    @Setter
    @Getter
    private Application application;
    @Setter
    @Getter
    private SchemaManager schemaManager;
    @Setter
    @Getter
    private IndexManager indexManager;
    @Setter
    @Getter
    private RouteOptimizer routeOptimizer;
    @Setter
    @Getter
    private IOptimizer optimizer;
    @Setter
    @Getter
    private SqlParseManager sqlParseManager;
    @Setter
    @Getter
    private StatisticsManager statisticsManager;

    public static OptimizerContext getOptimizerContext() {
        return (OptimizerContext) ThreadLocalMap.get(OPTIMIZER_CONTEXT_KEY);
    }

    public static void setOptimizerContext(OptimizerContext optimizerContext) {
        ThreadLocalMap.put(OPTIMIZER_CONTEXT_KEY, optimizerContext);
    }

}
